home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- __revision__ = '$Id: vcard.py 675 2007-06-28 08:36:17Z jajcus $'
- __docformat__ = 'restructuredtext en'
- import base64
- import binascii
- import libxml2
- import re
- import pyxmpp.jid as pyxmpp
- from pyxmpp.utils import to_utf8, from_utf8
- from pyxmpp.xmlextra import get_node_ns
- from pyxmpp.objects import StanzaPayloadObject
- from pyxmpp.exceptions import BadRequestProtocolError, JIDMalformedProtocolError, JIDError
- VCARD_NS = 'vcard-temp'
-
- class Empty(Exception):
- pass
-
- valid_string_re = re.compile('^[\\w\\d \\t]*$')
- non_quoted_semicolon_re = re.compile('(?<!\\\\);')
-
- def quote_semicolon(value):
- return value.replace(';', '\\;')
-
-
- def unquote_semicolon(value):
- return value.replace('\\;', ';')
-
-
- def rfc2425encode(name, value, parameters = None, charset = 'utf-8'):
- if not parameters:
- parameters = { }
-
- if type(value) is unicode:
- value = value.replace(u'\r\n', u'\\n')
- value = value.replace(u'\n', u'\\n')
- value = value.replace(u'\r', u'\\n')
- value = value.encode(charset, 'replace')
- elif type(value) is not str:
- raise TypeError, 'Bad type for rfc2425 value'
- elif not valid_string_re.match(value):
- parameters['encoding'] = 'b'
- value = binascii.b2a_base64(value)
-
- ret = str(name).lower()
- for k, v in parameters.items():
- ret += ';%s=%s' % (str(k), str(v))
-
- ret += ':'
- while len(value) > 70:
- ret += value[:70] + '\r\n '
- value = value[70:]
- ret += value + '\r\n'
- return ret
-
-
- class VCardField:
-
- def __init__(self, name):
- self.name = name
-
-
- def __repr__(self):
- return '<%s %r>' % (self.__class__, self.rfc2426())
-
-
- def rfc2426(self):
- return ''
-
-
-
- class VCardString(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None, empty_ok = False):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if isinstance(value, libxml2.xmlNode):
- value = value.getContent()
- if value:
- self.value = unicode(value, 'utf-8', 'replace').strip()
- else:
- self.value = u''
- else:
- self.value = value
- if not (self.value) and not empty_ok:
- raise Empty, 'Empty string value'
-
-
-
- def rfc2426(self):
- return rfc2425encode(self.name, self.value)
-
-
- def as_xml(self, parent):
- return parent.newTextChild(None, to_utf8(self.name.upper()), to_utf8(self.value))
-
-
- def __unicode__(self):
- return self.value
-
-
- def __str__(self):
- return self.value.encode('utf-8')
-
-
-
- class VCardXString(VCardString):
-
- def rfc2426(self):
- return rfc2425encode('x-' + self.name, self.value)
-
-
-
- class VCardJID(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if isinstance(value, libxml2.xmlNode):
-
- try:
- self.value = pyxmpp.jid.JID(value.getContent())
- except JIDError:
- raise JIDMalformedProtocolError, 'JID malformed'
- except:
- None<EXCEPTION MATCH>JIDError
-
-
- None<EXCEPTION MATCH>JIDError
- self.value = pyxmpp.jid.JID(value)
- if not self.value:
- raise Empty, 'Empty JID value'
-
-
-
- def rfc2426(self):
- return rfc2425encode('x-jabberid', self.value.as_unicode())
-
-
- def as_xml(self, parent):
- name = to_utf8(self.name.upper())
- content = self.value.as_utf8()
- return parent.newTextChild(None, name, content)
-
-
- def __unicode__(self):
- return self.value.as_unicode()
-
-
- def __str__(self):
- return self.value.as_string()
-
-
-
- class VCardName(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if self.name.upper() != 'N':
- raise RuntimeError, "VCardName handles only 'N' type"
-
- if isinstance(value, libxml2.xmlNode):
- (self.family, self.given, self.middle, self.prefix, self.suffix) = [
- u''] * 5
- empty = 1
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'FAMILY':
- self.family = unicode(n.getContent(), 'utf-8')
- empty = 0
-
- if n.name == 'GIVEN':
- self.given = unicode(n.getContent(), 'utf-8')
- empty = 0
-
- if n.name == 'MIDDLE':
- self.middle = unicode(n.getContent(), 'utf-8')
- empty = 0
-
- if n.name == 'PREFIX':
- self.prefix = unicode(n.getContent(), 'utf-8')
- empty = 0
-
- if n.name == 'SUFFIX':
- self.suffix = unicode(n.getContent(), 'utf-8')
- empty = 0
-
- n = n.next
- if empty:
- raise Empty, 'Empty N value'
-
- else:
- v = non_quoted_semicolon_re.split(value)
- value = [
- u''] * 5
- value[:len(v)] = v
- (self.family, self.given, self.middle, self.prefix, self.suffix) = (lambda .0: for val in .0:
- unquote_semicolon(val))(value)
-
-
- def rfc2426(self):
- return rfc2425encode('n', u';'.join((lambda .0: for val in .0:
- quote_semicolon(val))((self.family, self.given, self.middle, self.prefix, self.suffix))))
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'N', None)
- n.newTextChild(None, 'FAMILY', to_utf8(self.family))
- n.newTextChild(None, 'GIVEN', to_utf8(self.given))
- n.newTextChild(None, 'MIDDLE', to_utf8(self.middle))
- n.newTextChild(None, 'PREFIX', to_utf8(self.prefix))
- n.newTextChild(None, 'SUFFIX', to_utf8(self.suffix))
- return n
-
-
- def __unicode__(self):
- r = []
- if self.prefix:
- r.append(self.prefix.replace(u',', u' '))
-
- if self.given:
- r.append(self.given.replace(u',', u' '))
-
- if self.middle:
- r.append(self.middle.replace(u',', u' '))
-
- if self.family:
- r.append(self.family.replace(u',', u' '))
-
- if self.suffix:
- r.append(self.suffix.replace(u',', u' '))
-
- return u' '.join(r)
-
-
- def __str__(self):
- return self.__unicode__().encode('utf-8')
-
-
-
- class VCardImage(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- (self.uri, self.type, self.image) = [
- None] * 3
- if isinstance(value, libxml2.xmlNode):
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'TYPE':
- self.type = unicode(n.getContent(), 'utf-8', 'replace')
-
- if n.name == 'BINVAL':
-
- try:
- self.image = base64.decodestring(n.getContent())
- self.image = None
-
-
- if n.name == 'EXTVAL':
- self.uri = unicode(n.getContent(), 'utf-8', 'replace')
-
- n = n.next
- if self.uri and self.image:
- raise ValueError, 'Bad %s value in vcard' % (name,)
-
- if not (self.uri) and not (self.image):
- raise Empty, 'Bad %s value in vcard' % (name,)
-
- elif rfc2425parameters.get('value', '').lower() == 'uri':
- self.uri = value
- self.type = None
- else:
- self.type = rfc2425parameters.get('type')
- self.image = value
-
-
- def rfc2426(self):
- if self.uri:
- return rfc2425encode(self.name, self.uri, {
- 'value': 'uri' })
- elif self.image:
- if self.type:
- p = {
- 'type': self.type }
- else:
- p = { }
- return rfc2425encode(self.name, self.image, p)
-
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, self.name.upper(), None)
- if self.uri:
- n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
- elif self.type:
- n.newTextChild(None, 'TYPE', self.type)
-
- n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.image))
- return n
-
-
- def __unicode__(self):
- if self.uri:
- return self.uri
-
- if self.type:
- return u'(%s data)' % (self.type,)
-
- return u'(binary data)'
-
-
- def __str__(self):
- return self.__unicode__().encode('utf-8')
-
-
-
- class VCardAdr(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- if self.name.upper() != 'ADR':
- raise RuntimeError, "VCardAdr handles only 'ADR' type"
-
- (self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = [
- ''] * 7
- self.type = []
- if isinstance(value, libxml2.xmlNode):
- self._VCardAdr__from_xml(value)
- else:
- t = rfc2425parameters.get('type')
- if t:
- self.type = t.split(',')
- else:
- self.type = [
- 'intl',
- 'postal',
- 'parcel',
- 'work']
- v = non_quoted_semicolon_re.split(value)
- value = [
- ''] * 7
- value[:len(v)] = v
- (self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = (lambda .0: for val in .0:
- unquote_semicolon(val))(value)
-
-
- def __from_xml(self, value):
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'POBOX':
- self.pobox = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name in ('EXTADR', 'EXTADD'):
- self.extadr = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name == 'STREET':
- self.street = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name == 'LOCALITY':
- self.locality = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name == 'REGION':
- self.region = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name == 'PCODE':
- self.pcode = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name == 'CTRY':
- self.ctry = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
- self.type.append(n.name.lower())
-
- n = n.next
- if self.type == []:
- self.type = [
- 'intl',
- 'postal',
- 'parcel',
- 'work']
- elif 'dom' in self.type and 'intl' in self.type:
- raise ValueError, "Both 'dom' and 'intl' specified in vcard ADR"
-
-
-
- def rfc2426(self):
- return rfc2425encode('adr', u';'.join((lambda .0: for val in .0:
- quote_semicolon(val))((self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry))), {
- 'type': ','.join(self.type) })
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'ADR', None)
- for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
- if t in self.type:
- n.newChild(None, t.upper(), None)
- continue
-
- n.newTextChild(None, 'POBOX', to_utf8(self.pobox))
- n.newTextChild(None, 'EXTADD', to_utf8(self.extadr))
- n.newTextChild(None, 'STREET', to_utf8(self.street))
- n.newTextChild(None, 'LOCALITY', to_utf8(self.locality))
- n.newTextChild(None, 'REGION', to_utf8(self.region))
- n.newTextChild(None, 'PCODE', to_utf8(self.pcode))
- n.newTextChild(None, 'CTRY', to_utf8(self.ctry))
- return n
-
-
-
- class VCardLabel(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- if self.name.upper() != 'LABEL':
- raise RuntimeError, "VCardAdr handles only 'LABEL' type"
-
- if isinstance(value, libxml2.xmlNode):
- self.lines = []
- self.type = []
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'LINE':
- l = unicode(n.getContent(), 'utf-8', 'replace').strip()
- l = l.replace('\n', ' ').replace('\r', ' ')
- self.lines.append(l)
- elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
- self.type.append(n.name.lower())
-
- n = n.next
- if self.type == []:
- self.type = [
- 'intl',
- 'postal',
- 'parcel',
- 'work']
- elif 'dom' in self.type and 'intl' in self.type:
- raise ValueError, "Both 'dom' and 'intl' specified in vcard LABEL"
-
- if not self.lines:
- self.lines = [
- '']
-
- else:
- t = rfc2425parameters.get('type')
- if t:
- self.type = t.split(',')
- else:
- self.type = [
- 'intl',
- 'postal',
- 'parcel',
- 'work']
- self.lines = value.split('\\n')
-
-
- def rfc2426(self):
- return rfc2425encode('label', u'\n'.join(self.lines), {
- 'type': ','.join(self.type) })
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'ADR', None)
- for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
- if t in self.type:
- n.newChild(None, t.upper(), None)
- continue
-
- for l in self.lines:
- n.newTextChild(None, 'LINE', l)
-
- return n
-
-
-
- class VCardTel(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- if self.name.upper() != 'TEL':
- raise RuntimeError, "VCardTel handles only 'TEL' type"
-
- if isinstance(value, libxml2.xmlNode):
- self.number = None
- self.type = []
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'NUMBER':
- self.number = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name in ('HOME', 'WORK', 'VOICE', 'FAX', 'PAGER', 'MSG', 'CELL', 'VIDEO', 'BBS', 'MODEM', 'ISDN', 'PCS', 'PREF'):
- self.type.append(n.name.lower())
-
- n = n.next
- if self.type == []:
- self.type = [
- 'voice']
-
- if not self.number:
- raise Empty, 'No tel number'
-
- else:
- t = rfc2425parameters.get('type')
- if t:
- self.type = t.split(',')
- else:
- self.type = [
- 'voice']
- self.number = value
-
-
- def rfc2426(self):
- return rfc2425encode('tel', self.number, {
- 'type': ','.join(self.type) })
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'TEL', None)
- for t in ('home', 'work', 'voice', 'fax', 'pager', 'msg', 'cell', 'video', 'bbs', 'modem', 'isdn', 'pcs', 'pref'):
- if t in self.type:
- n.newChild(None, t.upper(), None)
- continue
-
- n.newTextChild(None, 'NUMBER', to_utf8(self.number))
- return n
-
-
-
- class VCardEmail(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- if self.name.upper() != 'EMAIL':
- raise RuntimeError, "VCardEmail handles only 'EMAIL' type"
-
- if isinstance(value, libxml2.xmlNode):
- self.address = None
- self.type = []
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'USERID':
- self.address = unicode(n.getContent(), 'utf-8', 'replace')
- elif n.name in ('HOME', 'WORK', 'INTERNET', 'X400'):
- self.type.append(n.name.lower())
-
- n = n.next
- if self.type == []:
- self.type = [
- 'internet']
-
- if not self.address:
- raise Empty, 'No USERID'
-
- else:
- t = rfc2425parameters.get('type')
- if t:
- self.type = t.split(',')
- else:
- self.type = [
- 'internet']
- self.address = value
-
-
- def rfc2426(self):
- return rfc2425encode('email', self.address, {
- 'type': ','.join(self.type) })
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'EMAIL', None)
- for t in ('home', 'work', 'internet', 'x400'):
- if t in self.type:
- n.newChild(None, t.upper(), None)
- continue
-
- n.newTextChild(None, 'USERID', to_utf8(self.address))
- return n
-
-
-
- class VCardGeo(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if self.name.upper() != 'GEO':
- raise RuntimeError, "VCardName handles only 'GEO' type"
-
- if isinstance(value, libxml2.xmlNode):
- (self.lat, self.lon) = [
- None] * 2
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'LAT':
- self.lat = unicode(n.getContent(), 'utf-8')
-
- if n.name == 'LON':
- self.lon = unicode(n.getContent(), 'utf-8')
-
- n = n.next
- if not (self.lat) or not (self.lon):
- raise ValueError, 'Bad vcard GEO value'
-
- else:
- (self.lat, self.lon) = (lambda .0: for val in .0:
- unquote_semicolon(val))(non_quoted_semicolon_re.split(value))
-
-
- def rfc2426(self):
- return rfc2425encode('geo', u';'.join((lambda .0: for val in .0:
- quote_semicolon(val))((self.lat, self.lon))))
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'GEO', None)
- n.newTextChild(None, 'LAT', to_utf8(self.lat))
- n.newTextChild(None, 'LON', to_utf8(self.lon))
- return n
-
-
-
- class VCardOrg(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if self.name.upper() != 'ORG':
- raise RuntimeError, "VCardName handles only 'ORG' type"
-
- if isinstance(value, libxml2.xmlNode):
- (self.name, self.unit) = (None, '')
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'ORGNAME':
- self.name = unicode(n.getContent(), 'utf-8')
-
- if n.name == 'ORGUNIT':
- self.unit = unicode(n.getContent(), 'utf-8')
-
- n = n.next
- if not self.name:
- raise Empty, 'Bad vcard ORG value'
-
- else:
- sp = non_quoted_semicolon_re.split(value, 1)
- if len(sp) > 1:
- (self.name, self.unit) = (lambda .0: for val in .0:
- unquote_semicolon(val))(sp)
- else:
- self.name = unquote_semicolon(sp[0])
- self.unit = None
-
-
- def rfc2426(self):
- if self.unit:
- return rfc2425encode('org', u';'.join((lambda .0: for val in .0:
- quote_semicolon(val))((self.name, self.unit))))
- else:
- return rfc2425encode('org', unicode(quote_semicolon(self.name)))
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'ORG', None)
- n.newTextChild(None, 'ORGNAME', to_utf8(self.name))
- n.newTextChild(None, 'ORGUNIT', to_utf8(self.unit))
- return n
-
-
-
- class VCardCategories(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- self.name = name
- if self.name.upper() != 'CATEGORIES':
- raise RuntimeError, "VCardName handles only 'CATEGORIES' type"
-
- if isinstance(value, libxml2.xmlNode):
- self.keywords = []
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'KEYWORD':
- self.keywords.append(unicode(n.getContent(), 'utf-8'))
-
- n = n.next
- if not self.keywords:
- raise Empty, 'Bad vcard CATEGORIES value'
-
- else:
- self.keywords = value.split(',')
-
-
- def rfc2426(self):
- return rfc2425encode('keywords', u','.join(self.keywords))
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, 'CATEGORIES', None)
- for k in self.keywords:
- n.newTextChild(None, 'KEYWORD', to_utf8(k))
-
- return n
-
-
-
- class VCardSound(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- (self.uri, self.sound, self.phonetic) = [
- None] * 3
- if isinstance(value, libxml2.xmlNode):
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'BINVAL':
- if self.phonetic or self.uri:
- raise ValueError, 'Bad SOUND value in vcard'
-
- self.sound = base64.decodestring(n.getContent())
-
- if n.name == 'PHONETIC':
- if self.sound or self.uri:
- raise ValueError, 'Bad SOUND value in vcard'
-
- self.phonetic = unicode(n.getContent(), 'utf-8', 'replace')
-
- if n.name == 'EXTVAL':
- if self.phonetic or self.sound:
- raise ValueError, 'Bad SOUND value in vcard'
-
- self.uri = unicode(n.getContent(), 'utf-8', 'replace')
-
- n = n.next
- if not (self.phonetic) and not (self.uri) and not (self.sound):
- raise Empty, 'Bad SOUND value in vcard'
-
- elif rfc2425parameters.get('value', '').lower() == 'uri':
- self.uri = value
- self.sound = None
- self.phonetic = None
- else:
- self.sound = value
- self.uri = None
- self.phonetic = None
-
-
- def rfc2426(self):
- if self.uri:
- return rfc2425encode(self.name, self.uri, {
- 'value': 'uri' })
- elif self.sound:
- return rfc2425encode(self.name, self.sound)
-
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, self.name.upper(), None)
- if self.uri:
- n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
- elif self.phonetic:
- n.newTextChild(None, 'PHONETIC', to_utf8(self.phonetic))
- else:
- n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.sound))
- return n
-
-
-
- class VCardPrivacy(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- _unused = rfc2425parameters
- VCardField.__init__(self, name)
- if isinstance(value, libxml2.xmlNode):
- self.value = None
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'PUBLIC':
- self.value = 'public'
- elif n.name == 'PRIVATE':
- self.value = 'private'
- elif n.name == 'CONFIDENTAL':
- self.value = 'confidental'
-
- n = n.next
- if not self.value:
- raise Empty
-
- else:
- self.value = value
-
-
- def rfc2426(self):
- return rfc2425encode(self.name, self.value)
-
-
- def as_xml(self, parent):
- if self.value in ('public', 'private', 'confidental'):
- n = parent.newChild(None, self.name.upper(), None)
- n.newChild(None, self.value.upper(), None)
- return n
-
-
-
-
- class VCardKey(VCardField):
-
- def __init__(self, name, value, rfc2425parameters = None):
- VCardField.__init__(self, name)
- if not rfc2425parameters:
- rfc2425parameters = { }
-
- if isinstance(value, libxml2.xmlNode):
- (self.type, self.cred) = (None, None)
- n = value.children
- vns = get_node_ns(value)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and vns and ns.getContent() != vns.getContent():
- n = n.next
- continue
-
- if n.name == 'TYPE':
- self.type = unicode(n.getContent(), 'utf-8', 'replace')
-
- if n.name == 'CRED':
- self.cred = base64.decodestring(n.getContent())
-
- n = n.next
- if not self.cred:
- raise Empty, 'Bad %s value in vcard' % (name,)
-
- else:
- self.type = rfc2425parameters.get('type')
- self.cred = value
-
-
- def rfc2426(self):
- if self.type:
- p = {
- 'type': self.type }
- else:
- p = { }
- return rfc2425encode(self.name, self.cred, p)
-
-
- def as_xml(self, parent):
- n = parent.newChild(None, self.name.upper(), None)
- if self.type:
- n.newTextChild(None, 'TYPE', self.type)
-
- n.newTextChild(None, 'CRED', binascii.b2a_base64(self.cred))
- return n
-
-
-
- class VCard(StanzaPayloadObject):
- xml_element_name = 'vCard'
- xml_element_namespace = VCARD_NS
- components = {
- 'FN': (VCardString, 'required'),
- 'N': (VCardName, 'required'),
- 'NICKNAME': (VCardString, 'multi'),
- 'PHOTO': (VCardImage, 'multi'),
- 'BDAY': (VCardString, 'multi'),
- 'ADR': (VCardAdr, 'multi'),
- 'LABEL': (VCardLabel, 'multi'),
- 'TEL': (VCardTel, 'multi'),
- 'EMAIL': (VCardEmail, 'multi'),
- 'JABBERID': (VCardJID, 'multi'),
- 'MAILER': (VCardString, 'multi'),
- 'TZ': (VCardString, 'multi'),
- 'GEO': (VCardGeo, 'multi'),
- 'TITLE': (VCardString, 'multi'),
- 'ROLE': (VCardString, 'multi'),
- 'LOGO': (VCardImage, 'multi'),
- 'AGENT': ('VCardAgent', 'ignore'),
- 'ORG': (VCardOrg, 'multi'),
- 'CATEGORIES': (VCardCategories, 'multi'),
- 'NOTE': (VCardString, 'multi'),
- 'PRODID': (VCardString, 'multi'),
- 'REV': (VCardString, 'multi'),
- 'SORT-STRING': (VCardString, 'multi'),
- 'SOUND': (VCardSound, 'multi'),
- 'UID': (VCardString, 'multi'),
- 'URL': (VCardString, 'multi'),
- 'CLASS': (VCardString, 'multi'),
- 'KEY': (VCardKey, 'multi'),
- 'DESC': (VCardXString, 'multi') }
-
- def __init__(self, data):
- self.n = None
- del self.n
- self.content = { }
- if isinstance(data, libxml2.xmlNode):
- self._VCard__from_xml(data)
- else:
- self._VCard__from_rfc2426(data)
- if not self.content.get('N') and self.content.get('FN'):
- s = self.content['FN'].value.replace(';', ',')
- s = s.split(None, 2)
- if len(s) == 2:
- s = u'%s;%s;;;' % (s[1], s[0])
- elif len(s) == 3:
- s = u'%s;%s;%s' % (s[2], s[0], s[1])
- else:
- s = u'%s;;;;' % (s[0],)
- self.content['N'] = VCardName('N', s)
- elif not self.content.get('FN') and self.content.get('N'):
- self._VCard__make_fn()
-
- for _unused, tp in self.components.items():
- if self.content.has_key(c):
- continue
-
- if tp == 'required':
- raise ValueError, '%s is missing' % (c,)
- continue
- if tp == 'multi':
- self.content[c] = []
- continue
- if tp == 'optional':
- self.content[c] = None
- continue
-
-
-
- def __make_fn(self):
- s = []
- if self.n.prefix:
- s.append(self.n.prefix)
-
- if self.n.given:
- s.append(self.n.given)
-
- if self.n.middle:
- s.append(self.n.middle)
-
- if self.n.family:
- s.append(self.n.family)
-
- if self.n.suffix:
- s.append(self.n.suffix)
-
- s = u' '.join(s)
- self.content['FN'] = VCardString('FN', s, empty_ok = True)
-
-
- def __from_xml(self, data):
- ns = get_node_ns(data)
- if ns and ns.getContent() != VCARD_NS:
- raise ValueError, 'Not in the %r namespace' % (VCARD_NS,)
-
- if data.name.lower() != 'vCard'.lower():
- raise ValueError, 'Bad root element name: %r' % (data.name,)
-
- n = data.children
- dns = get_node_ns(data)
- while n:
- if n.type != 'element':
- n = n.next
- continue
-
- ns = get_node_ns(n)
- if ns and dns and ns.getContent() != dns.getContent():
- n = n.next
- continue
-
- if not self.components.has_key(n.name):
- n = n.next
- continue
-
- (cl, tp) = self.components[n.name]
- if tp in ('required', 'optional'):
- if self.content.has_key(n.name):
- raise ValueError, 'Duplicate %s' % (n.name,)
-
-
- try:
- self.content[n.name] = cl(n.name, n)
- except Empty:
- pass
- except:
- None<EXCEPTION MATCH>Empty
-
-
- None<EXCEPTION MATCH>Empty
- if tp == 'multi':
- if not self.content.has_key(n.name):
- self.content[n.name] = []
-
-
- try:
- self.content[n.name].append(cl(n.name, n))
- except Empty:
- pass
- except:
- None<EXCEPTION MATCH>Empty
-
-
- None<EXCEPTION MATCH>Empty
- n = n.next
-
-
- def __from_rfc2426(self, data):
- data = from_utf8(data)
- lines = data.split('\n')
- started = 0
- current = None
- for l in lines:
- if not l:
- continue
-
- if l[-1] == '\r':
- l = l[:-1]
-
- if not l:
- continue
-
- if l[0] in ' \t':
- if current is None:
- continue
-
- current += l[1:]
- continue
-
- if not started and current and current.upper().strip() == 'BEGIN:VCARD':
- started = 1
- elif started and current.upper().strip() == 'END:VCARD':
- current = None
- break
- elif current and started:
- self._process_rfc2425_record(current)
-
- current = l
-
- if started and current:
- self._process_rfc2425_record(current)
-
-
-
- def _process_rfc2425_record(self, data):
- (label, value) = data.split(':', 1)
- value = value.replace('\\n', '\n').replace('\\N', '\n')
- psplit = label.lower().split(';')
- name = psplit[0]
- params = psplit[1:]
- if u'.' in name:
- name = name.split('.', 1)[1]
-
- name = name.upper()
- if name in (u'X-DESC', u'X-JABBERID'):
- name = name[2:]
-
- if not self.components.has_key(name):
- return None
-
- (cl, tp) = self.components[name]
- if tp in ('required', 'optional'):
- if self.content.has_key(name):
- raise ValueError, 'Duplicate %s' % (name,)
-
-
- try:
- self.content[name] = cl(name, value, params)
- except Empty:
- pass
- except:
- None<EXCEPTION MATCH>Empty
-
-
- None<EXCEPTION MATCH>Empty
- if tp == 'multi':
- if not self.content.has_key(name):
- self.content[name] = []
-
-
- try:
- self.content[name].append(cl(name, value, params))
- except Empty:
- pass
- except:
- None<EXCEPTION MATCH>Empty
-
-
- None<EXCEPTION MATCH>Empty
- return None
-
-
- def __repr__(self):
- return '<vCard of %r>' % (self.content['FN'].value,)
-
-
- def rfc2426(self):
- ret = 'begin:VCARD\r\n'
- ret += 'version:3.0\r\n'
- for _unused, value in self.content.items():
- if value is None:
- continue
-
- if type(value) is list:
- for v in value:
- ret += v.rfc2426()
-
- v = value.rfc2426()
- ret += v
-
- return ret + 'end:VCARD\r\n'
-
-
- def complete_xml_element(self, xmlnode, _unused):
- for _unused1, value in self.content.items():
- if value is None:
- continue
-
- if type(value) is list:
- for v in value:
- v.as_xml(xmlnode)
-
- value.as_xml(xmlnode)
-
-
-
- def __getattr__(self, name):
-
- try:
- return self.content[name.upper().replace('_', '-')]
- except KeyError:
- raise AttributeError, 'Attribute %r not found' % (name,)
-
-
-
- def __getitem__(self, name):
- return self.content[name.upper()]
-
-
-